unit main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Win.ScktComp, Vcl.ExtCtrls,
  Vcl.StdCtrls, mcSettings, fScreenshot, mcCommands;

type
  TForm2 = class(TForm)
    socket: TClientSocket;
    btn1: TButton;
    tmr1: TTimer;
    btn2: TButton;
    procedure tmr1Timer(Sender: TObject);
    procedure socketDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure socketError(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure socketRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure btn2Click(Sender: TObject);

    procedure interpretpackage(com: RCommand); overload;
    procedure interpretack(ack: RAck);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    settings: SSettings;

    status: DWORD;

    procedure loadSettings;
    procedure install;
  public
    { Public declarations }
  end;

var
  Form2: TForm2;
  lastchecksum: dword;

const

  STATUS_WAITING = $DADE;
  S_PONGSENT = $342;

implementation

{$R *.dfm}

procedure TForm2.interpretack(ack: RAck);
var
  ncom: RCommand;
begin
  ShowMessage('ackthere');
  case status of
  S_PONGSENT:
    begin
      if (ack.magic <> MAGIC_DWORD) or (ack.ack <> lastchecksum) then
      begin
        ncom.magic := MAGIC_DWORD;
        ncom.command := COM_PONG;
        ncom.data := DATA_EMPTY;
        lastchecksum := Random(CHECKSUM_RAND);
        ncom.checksum := lastchecksum;
        status := S_PONGSENT;
      end else
      begin
        status := STATUS_WAITING;
        ShowMessage('aslkdjfasdklf');
      end;

    end;
  end;
end;

procedure TForm2.interpretpackage(com: RCommand);
var
  ack: RAck;
  ncom: RCommand;
  sendback: Boolean;
begin
  //ga;skl
  showmessage('packagethere');
  sendback := false;
  if com.magic <> MAGIC_DWORD then
  begin
    ack.magic := COM_RESEND_COM;
    ack.ack := COM_RESEND_COM;
  end else
  begin
    ack.magic := MAGIC_DWORD;
    case status of
    STATUS_WAITING:
      begin
        ack.ack := com.checksum;

        case com.command of
        COM_SCREEN:
          begin

          end;
        COM_PING:
          begin
            ncom.magic := MAGIC_DWORD;
            ncom.command := COM_PONG;
            ncom.data := DATA_EMPTY;
            lastchecksum := Random(CHECKSUM_RAND);
            ncom.checksum := lastchecksum;
            status := S_PONGSENT;
            sendback := true;
          end;
        end;

        //socket.Socket.SendBuf(ack, SizeOf(ack));

        if sendback then
          socket.Socket.SendBuf(ncom, SizeOf(ncom));

      end;
    end;
  end;
end;

procedure TForm2.loadSettings;
begin
  //asdfsdfad
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  Randomize;
  status := STATUS_WAITING;
end;

procedure TForm2.install;
begin
  //adsf
end;

procedure TForm2.btn2Click(Sender: TObject);
var
  scrn: CScreenshot;
begin
//  scrn := CScreenshot.Create(socket.Socket);
//  scrn.screenshot;
  socket.Host := 'localhost';
  socket.Port := 4815;
  socket.Active := true;
end;

procedure TForm2.socketDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
// :(
  tmr1.Enabled := true;
end;

procedure TForm2.socketError(Sender: TObject; Socket: TCustomWinSocket;
  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
//:((
  tmr1.Enabled := true;
  errorcode := 0;
end;

procedure TForm2.socketRead(Sender: TObject; Socket: TCustomWinSocket);
var
  //cs: TClientSession;
  //lpBuffer: Pointer;
  //strBuffer: string;
  //dwLen, dwRecv: DWORD;
  com: RCommand;
  ack: RAck;
begin
//reading something
//  dwLen := socket.ReceiveLength;
//
//  if dwLen > 0 then
//  begin
//    GetMem(lpBuffer, dwLen + 1);
//
//    ZeroMemory(lpBuffer, dwLen + 1);
//
//    //cs := TClientSession(socket.Data);
//
//    dwRecv := socket.ReceiveBuf(lpBuffer^, dwLen);
//
//
//    if dwRecv > 0 then
//    begin
//      //interpretPackage(lpBuffer);
//    end;
//
//    FreeMemory(lpBuffer);
//
//  end;
  case(status) of
  STATUS_WAITING:
    begin
      if Socket.ReceiveLength = SizeOf(com) then
      begin
        socket.ReceiveBuf(com, SizeOf(com));
        interpretpackage(com);
      end;
    end;
  S_PONGSENT:
    begin
      if socket.ReceiveLength = sizeof(ack) then
      begin
        socket.ReceiveBuf(ack, SizeOf(ack));
        interpretack(ack);
      end;
    end;

  end;


end;

procedure TForm2.tmr1Timer(Sender: TObject);
begin
  if socket.Active then
    tmr1.Enabled := false
  else
    socket.Active := true;
end;

end.
